// #ifndef __THREAD_POOL__
// #define __THREAD_POOL__

// #include <iostream>
// #include <thread>
// #include <condition_variable>
// #include <queue>
// #include <atomic>
// #include <functional>
// #include <mutex>
// #include <unistd.h>
// #include <memory>
// #include <unordered_map>
// #include <future>

// #define DEBUG 1

// const int TASK_MAX_THRESHHOLD = 30;    // 任务队列上限阈值
// const int THREAD_MAX_THRESHHOLD = 10; // 线程数量上限阈值
// const int THREAD_MAX_IDLE_TIME = 10;  // 多久没有新任务,多余的线程被回收

// class Thread
// {

// public:
//     using Func_t = std::function<void(int)>;
//     Thread(Func_t func) : _func(func), _threadId(_ThreadNum)
//     {
//         _ThreadNum++;
//     }
//     ~Thread() {}

//     void start()
//     {
//         std::thread t(_func, _threadId);
//         t.detach(); // 如果不设置为分离线程,出了start作用域即被析构
//     }
//     int GetThreadId() const
//     {
//         return _threadId;
//     }

// private:
//     int _threadId;
//     Func_t _func;
//     static int _ThreadNum;
// };

// int Thread::_ThreadNum;

// enum class PoolMode
// {
//     MODE_FIXED,
//     MODE_CACHED
// };

// class ThreadPool
// {
// public:
//     ThreadPool(int size=THREAD_MAX_THRESHHOLD) : initThreadSize_(4),
//                    TaskSize_(0),
//                    taskQueMaxThreadHold_(TASK_MAX_THRESHHOLD),
//                    poolMode_(PoolMode::MODE_FIXED),
//                    isPoolRunning_(false),
//                    idleThreadSize_(0),
//                    threadSizeThreshHold_(size),
//                    curThreadSize_(0)
//     {
//     }

//     ThreadPool(const ThreadPool &) = delete;
//     ThreadPool &operator=(const ThreadPool &) = delete;

//     ~ThreadPool()
//     {
//         isPoolRunning_ = false;
//         std::unique_lock<std::mutex> lock(taskQueMtx_);
//         //-------------------------------------
//         // TODO ? 是否要唤醒全部线程
//         //Anser: 一定要,问题答案在ThreadFun中
//         notEmpty_.notify_all();
//         //-------------------------------------
//         exitCond_.wait(lock, [&]() -> bool
//                        { return TaskSize_ == 0; });
//         std::cout << "任务执行完毕,exit"<<std::endl;
//     }

//     bool setMode(PoolMode poolmode)
//     {
//         if (checkRunningState())
//             return false;
//         poolMode_ = poolmode;
//         return true;
//     }

//     void setTaskQueMaxThreshHold(int threshHold)
//     {
//         taskQueMaxThreadHold_ = threshHold;
//     }
//     void start(int initThreadSize = std::thread::hardware_concurrency()) // 系统调用获取CUP数量
//     {
//         initThreadSize_ = initThreadSize;
//         isPoolRunning_ = true;
//         for (int i = 0; i < initThreadSize_; i++)
//         {
//             std::unique_ptr<Thread> thread = std::unique_ptr<Thread>(new Thread(std::bind(&ThreadPool::ThreadFunc, this, std::placeholders::_1)));
//             int threadId = thread->GetThreadId();
//             threads_.insert(std::make_pair(threadId, std::move(thread)));
//             curThreadSize_++;
//         }
//         for (int i = 0; i < curThreadSize_; i++)
//         {
//             std::cout << "线程: " << i << "  start  " << std::endl;

//             threads_[i]->start();
//             idleThreadSize_++;
//         }
//     }

//     template <class Func, class... Args>
//     auto submitTask(Func &&func, Args &&...args) -> std::future<decltype(func(args...))>
//     {
//         using RType = decltype(func(args...));
//         if (!isPoolRunning_)
//             return (std::packaged_task<RType()>([]() -> RType
//                                                 { return RType(); }))
//                 .get_future();

//         auto task = std::make_shared<std::packaged_task<RType()>>(std::bind(std::forward<Func>(func), std::forward<Args>(args)...));

//         std::future<RType> result = task->get_future();

//         std::unique_lock<std::mutex> lock(taskQueMtx_);
//         if (!notFull_.wait_for(lock, std::chrono::seconds(1), [&]() -> bool
//                                { return TaskQue_.size() < taskQueMaxThreadHold_; }))
//         {
//             std::cout << "submitask fail......" << std::endl;
//             auto task = std::make_shared<std::packaged_task<RType()>>([]() -> RType
//                                                                       { return RType(); });
//             (*task)();
//             return task->get_future();
//         }

//         TaskQue_.emplace([task]()
//                          { (*task)(); });

//         TaskSize_++;
//         std::cout << "submit success: " << TaskQue_.size() << std::endl;

//         notEmpty_.notify_all();

//         if (PoolMode::MODE_CACHED == poolMode_ && idleThreadSize_ < TaskSize_ && curThreadSize_ < threadSizeThreshHold_)
//         {
//             Thread_Create_And_Start();
//         }
//         return result;
//     };
//     void setThreadSizeThreshHold(int threshhold)
//     {
//         if (checkRunningState())
//             return;
//         if (poolMode_ == PoolMode::MODE_CACHED)
//             threadSizeThreshHold_ = threshhold;
//     }

// private:
//     void Thread_Create_And_Start()
//     {
//         std::unique_ptr<Thread> thread = std::unique_ptr<Thread>(new Thread(std::bind(&ThreadPool::ThreadFunc, this, std::placeholders::_1)));
//         int threadId = thread->GetThreadId();
//         threads_.insert(std::make_pair(threadId, std::move(thread)));
//         curThreadSize_++;
//         thread->start();
//         idleThreadSize_++;
//     }
//     void ThreadFunc(int ThreadId)
//     {
//         auto lastTime = std::chrono::high_resolution_clock().now();
//         for (;;)
//         {
//             Task task;
//             {
//                 std::unique_lock<std::mutex> lock(taskQueMtx_);
//                 std::cout << "线程: " << ThreadId << " 开始获取任务" << std::endl;
//                 while (TaskSize_ == 0)
//                 {
//                     if (!isPoolRunning_)
//                     {
//                         DeleteThread(ThreadId);
//                         exitCond_.notify_all();
//                         return;
//                     }
//                     if (poolMode_ == PoolMode::MODE_CACHED)
//                     {
//                         if (std::cv_status::timeout == notEmpty_.wait_for(lock, std::chrono::seconds(1)))
//                         {
//                             auto cur = std::chrono::high_resolution_clock().now();
//                             auto dur = std::chrono::duration_cast<std::chrono::seconds>(cur - lastTime);
//                             if (dur.count() >= THREAD_MAX_IDLE_TIME && curThreadSize_ > initThreadSize_)
//                             {
//                                 DeleteThread(ThreadId);
//                                 exitCond_.notify_all();
//                                 return;
//                             }
//                         }
//                     }
//                     else
//                     {
//                         //关于析构时是否要唤醒全部线程的证据
//                         //线程停留在此,析构时此线程一直被阻塞
//                         //必须唤醒
//                         notEmpty_.wait(lock);
//                     }
//                 }
//                 task = TaskQue_.front();
//                 TaskSize_--;
//                 idleThreadSize_--;
//                 TaskQue_.pop();
//                 std::cout << "线程: " << ThreadId << " 获取任务成功" << std::endl;
//             }

//             task();
//             idleThreadSize_++;
//             lastTime = std::chrono::high_resolution_clock().now();
//         }
//     }
//     bool checkRunningState() const
//     {
//         return isPoolRunning_;
//     }

//     void DeleteThread(int ThreadId)
//     {
//         threads_.erase(ThreadId);
//         curThreadSize_--;
//         idleThreadSize_--;
//     }

// private:
//     std::unordered_map<int, std::unique_ptr<Thread>> threads_; // 线程列表
//     PoolMode poolMode_;                                        // 线程池工作模式

//     // std::vector<std::unique_ptr<Thread>> threads_; // 线程列表
//     size_t initThreadSize_;          // 初始化线程数量
//     int threadSizeThreshHold_;       // 线程上限数量
//     std::atomic_int curThreadSize_;  // 当前线程数量
//     std::atomic_int idleThreadSize_; // 记录当前空闲线程的数量

//     using Task = std::function<void()>;
//     std::queue<Task> TaskQue_;  // 任务队列
//     std::atomic_uint TaskSize_; // 任务数量
//     int taskQueMaxThreadHold_;  // 任务队列数量上线阈值

//     std::mutex taskQueMtx_;            // 保证任务队列的线程安全
//     std::condition_variable notFull_;  // 任务队列不空
//     std::condition_variable notEmpty_; // 任务队列不满
//     std::condition_variable exitCond_; // 等待线程资源全部回收

//     std::atomic_bool isPoolRunning_; // 当前线程池的状态
// };

// #endif






#ifndef THREADPOOL_H
#define THREADPOOL_H

#include <mutex>
#include <condition_variable>
#include <queue>
#include <thread>
#include <functional>
class ThreadPool {
public:
    explicit ThreadPool(size_t threadCount = 8): pool_(std::make_shared<Pool>()) {
            assert(threadCount > 0);

            // 创建threadCount个子线程
            for(size_t i = 0; i < threadCount; i++) {
                std::thread([pool = pool_] {
                    std::unique_lock<std::mutex> locker(pool->mtx);
                    while(true) {
                        if(!pool->tasks.empty()) {
                            // 从任务队列中取一个任务
                            auto task = std::move(pool->tasks.front());
                            // 移除掉
                            pool->tasks.pop();
                            locker.unlock();
                            task();
                            locker.lock();
                        } 
                        else if(pool->isClosed) break;
                        else pool->cond.wait(locker);
                    }
                }).detach();// 线程分离
            }
    }

    ThreadPool() = default;

    ThreadPool(ThreadPool&&) = default;
    
    ~ThreadPool() {
        if(static_cast<bool>(pool_)) {
            {
                std::lock_guard<std::mutex> locker(pool_->mtx);
                pool_->isClosed = true;
            }
            pool_->cond.notify_all();
        }
    }

    template<class F>
    void AddTask(F&& task) {
        {
            std::lock_guard<std::mutex> locker(pool_->mtx);
            pool_->tasks.emplace(std::forward<F>(task));
        }
        pool_->cond.notify_one();
    }

private:
    // 结构体，池子
    struct Pool {
        std::mutex mtx;     // 互斥锁
        std::condition_variable cond;   // 条件变量
        bool isClosed;          // 是否关闭
        std::queue<std::function<void()>> tasks;    // 队列（保存的是任务）
    };
    std::shared_ptr<Pool> pool_;  //  池子
};


#endif //THREADPOOL_H